package com.ucode.application.helper;

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ucode.application.security.CurrentLoginUserService;
import com.ucode.crm.dictionary.ModuleType;
import com.ucode.crm.dictionary.TeamUserPower;
import com.ucode.crm.mode.CrmTeamUser;
import com.ucode.crm.service.CrmTeamUserService;
import com.ucode.sys.helper.DataPermissionHelper;
import com.ucode.tool.base.ResultCodeEnum;
import com.ucode.tool.exception.UcodeServiceException;
import com.ucode.tool.util.TransmittableThreadLocalUtil;
import cn.hutool.core.collection.CollUtil;

/**
 * 数据校验器
 * @author: liliang
 * @date: 2020年3月10日 下午6:37:02
 */
@Component
public class CrmDataPermissionVerifier {
    
    @Autowired
    private DataPermissionHelper dataPermissionHelper;
    @Autowired
    private CrmTeamUserService crmTeamUserService;
    @Autowired
    private CurrentLoginUserService currentLoginUserService;
    
    class Container{
        private List<Long> manageUsers;
        public Container(List<Long> manageUsers) {
            super();
            this.manageUsers = manageUsers;
        }
        public List<Long> getManageUsers() {
            return manageUsers;
        }
    }
    
    /**
     * 获取当前用户可以操作那些人的数据
     * @author liliang
     * @date 2020年2月11日
     * @param userId 用户Id
     * @param moduleCode 业务模块代码
     * @return 返回null,则代表管理全部用户，反之则返回管理的目标用户(包含自己)
     */
    public List<Long> getCurrentUserManageUsers(String moduleCode){
        Long currentUserId = currentLoginUserService.getCurrentUserId();
        return getUserManageUsers(currentUserId, moduleCode);
    }
    
    /**
     * 用户可以操作那些人的数据
     * @author liliang
     * @date 2020年3月20日
     * @param userId 用户Id
     * @param permission 业务模块代码
     * @return 返回null,则代表管理全部用户，反之则返回管理的目标用户
     */
    public List<Long> getUserManageUsers(Long userId ,String permission){
        String key = "umu:"+userId.toString();
        Object obj = TransmittableThreadLocalUtil.get(key);
        if(obj != null){
            Container container = (Container)obj;
            return container.getManageUsers();
        }else{
            List<Long> manageUsers = dataPermissionHelper.findUserManageUsers(userId, permission);
            TransmittableThreadLocalUtil.set(key, manageUsers);
            return manageUsers;
        }
    }
    
    /**
     * 获取并校验当前用户在业务模块下,可查看那些用户的数据(列表数据)</br>
     * 1、当检索用户为空时,则返回当前用户管辖的用户集合</br>
     * 2、当检索用户不为空时,则判断检索用户中是否有不是当前用户管辖的用户,有则抛异常，反之返回检索用户
     * @author liliang
     * @date 2020年3月6日
     * @param permission 业务模块代码
     * @param userIds 检索用户
     * @return 
     */
    public List<Long> getCheckCurrentUserManageUsers(String permission,List<Long> userIds){
        Long currentUserId = currentLoginUserService.getCurrentUserId();
        List<Long> currentUserManageUserIds = this.getUserManageUsers(currentUserId,permission);

        if(currentUserManageUserIds != null && currentUserManageUserIds.size() == 0){
            throw new UcodeServiceException(ResultCodeEnum.UN_DATA_PERMISSION);
        }
        
         //判断检索用户中是否有包含当前用户无权管辖的用户
        if(CollUtil.isNotEmpty(userIds) && CollUtil.isNotEmpty(currentUserManageUserIds) && !currentUserManageUserIds.containsAll(userIds)){
            throw new UcodeServiceException(ResultCodeEnum.UN_DATA_PERMISSION);
        }
        
        if(CollUtil.isEmpty(userIds)){
            userIds = currentUserManageUserIds;
        }
        
        return userIds;
    }
    
    /**
     * 校验并获取当前用户对目标业务数据的操作权限
     * @author liliang
     * @date 2020年3月10日
     * @param permission 业务模块代码
     * @param businessType 业务类型 
     * @param businessDataId 数据数据Id
     * @return 0->负责人1->读写2->只读
     */
    public Integer getCurrentUserPowerByBusinessData(String permission,ModuleType moduleType,Long businessDataId,List<Long> ownerUserIds){
        
        Long currentUserId = currentLoginUserService.getCurrentUserId();
        
        if(CollUtil.contains(ownerUserIds, currentUserId)){
            return TeamUserPower.owner.code;
        }
        List<Long> currentUserManageUserIds = this.getUserManageUsers(currentUserId,permission);
        if(currentUserManageUserIds == null)
            return TeamUserPower.owner.code;
        
        if(CollUtil.containsAny(currentUserManageUserIds, ownerUserIds)){
            return TeamUserPower.owner.code;
        }
        
        List<CrmTeamUser> teamUsers = crmTeamUserService.findList(businessDataId, moduleType.code);
        if(CollUtil.isNotEmpty(teamUsers)){
            List<Long> targetUsers = new ArrayList<Long>();
            for(CrmTeamUser crmTeamUser : teamUsers){
                if(crmTeamUser.getUserId().equals(currentUserId)){
                    return crmTeamUser.getPower();
                }
                targetUsers.add(crmTeamUser.getUserId());
            }
            if(CollUtil.containsAny(currentUserManageUserIds, targetUsers)){
                return TeamUserPower.read.code;
            }
        }
        
        throw new UcodeServiceException(ResultCodeEnum.UN_DATA_PERMISSION);
    }
    
    /**
     * 校验当前用户对目标业务数据的编辑权限
     * @author liliang
     * @date 2020年3月20日
     * @param permission
     * @param moduleType
     * @param businessDataId
     * @param ownerUserIds
     * @param errorMsgTemplate
     * @param errorMsgParams
     */
    public void checkCurrentUserWritePowerByBusinessData(String permission,ModuleType moduleType,Long businessDataId,List<Long> ownerUserIds,String errorMsgTemplate, Object... errorMsgParams){
        //校验数据编辑权限
        Long currentUserId = currentLoginUserService.getCurrentUserId();
        CrmTeamUser crmTeamUser = crmTeamUserService.find(businessDataId, moduleType.code, currentUserId);
        if(crmTeamUser == null || TeamUserPower.read.code == crmTeamUser.getPower().intValue()){
            List<Long> currentUserManageUserIds = this.getUserManageUsers(currentUserId,permission);
            if(currentUserManageUserIds != null && !CollUtil.containsAny(currentUserManageUserIds, ownerUserIds)){
                throw new UcodeServiceException(ResultCodeEnum.UN_DATA_PERMISSION.code,errorMsgTemplate,errorMsgParams);
            }
        }
    }
    
    /**
     * 校验当前用户对目标业务数据是否有负责人权限
     * @author liliang
     * @date 2020年3月20日
     * @param permission
     * @param moduleType
     * @param ownerUserIds
     * @param errorMsgTemplate
     * @param errorMsgParams
     */
    public void checkCurrentUserOwnerPowerByBusinessData(String permission,ModuleType moduleType,List<Long> ownerUserIds,String errorMsgTemplate, Object... errorMsgParams){
        List<Long> currentUserManageUserIds = this.getCurrentUserManageUsers(permission);
        if(currentUserManageUserIds != null && !CollUtil.containsAny(currentUserManageUserIds, ownerUserIds)){
            throw new UcodeServiceException(ResultCodeEnum.UN_DATA_PERMISSION.code,errorMsgTemplate,errorMsgParams);
        }
    }

}
